package com.wzy.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;


import java.util.Arrays;

/**
 * jwt令牌服务，实现生成jwt格式的令牌
 * 生成JWT令牌是由Spring Security OAuth2框架的内部机制完成的，其中涉及到配置TokenStore、JwtAccessTokenConverter等组件。
 */
@Configuration
public class TokenConfig {

    private static final String STRING_KEY = "mq123";//JWT签名的密钥


    @Autowired
    TokenStore tokenStore;

    @Autowired
    private JwtAccessTokenConverter accessTokenConverter;

//    @Bean
//    public TokenStore tokenStore() {
//        //使用内存存储令牌（普通令牌）
//        return new InMemoryTokenStore();
//    }

    /**
     * TokenStore是用于存储和管理令牌的组件
     * OAuth2框架会使用JwtAccessTokenConverter将认证信息转换成JWT格式的令牌，并使用TokenStore进行存储和管理。
     * @return
     */
    @Bean
    public TokenStore tokenStore(){
        return new JwtTokenStore(accessTokenConverter());
    }

    /**
     * JwtAccessTokenConverter是用于将OAuth2认证信息转换成JWT格式的组件，其注入到TokenStore中，从而实现了JWT令牌的生成。
     * @return
     */
    @Bean
    public JwtAccessTokenConverter accessTokenConverter(){
        //把自己设置的jwt签名加入accessTokenConverter中
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
        converter.setSigningKey(STRING_KEY);
        return converter;
    }

    /**
     * 授权服务中注入上面的TokenStore，并修改令牌管理器增加jwt相关的配置
     * @return
     */
    @Bean(name="authorizationServerTokenServicesCustom")
    public AuthorizationServerTokenServices tokenService() {
        DefaultTokenServices service=new DefaultTokenServices();
        service.setSupportRefreshToken(true);//支持刷新令牌
        service.setTokenStore(tokenStore);//令牌存储策略

        //创建了一个 TokenEnhancerChain 的实例，然后设置要在链中使用的令牌增强器列表。令牌增强器列表只包含一个元素，即一个 AccessTokenConverter 的实例
        TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
        tokenEnhancerChain.setTokenEnhancers(Arrays.asList(accessTokenConverter));
        service.setTokenEnhancer(tokenEnhancerChain);

        service.setAccessTokenValiditySeconds(7200); // 令牌默认有效期2小时
        service.setRefreshTokenValiditySeconds(259200); // 刷新令牌默认有效期3天
        return service;
    }


}
